package com.example.pt.service.impl;


import com.example.pt.dto.ApiResponse;
import com.example.pt.entity.Notification;
import com.example.pt.entity.User;
import com.example.pt.repository.NotificationRepository;
import com.example.pt.repository.UserRepository;
import com.example.pt.service.UserService;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
    private static final long GB = 1024L * 1024 * 1024;

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private NotificationRepository notificationRepository;

    private final SecureRandom random = new SecureRandom();


    private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    public UserServiceImpl(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    private final PasswordEncoder passwordEncoder;


    @Transactional
    @Override
    public ApiResponse<String> register(User user) {
        // 检查用户名是否存在
        if (userRepository.existsByUsername(user.getUsername())) {
            return ApiResponse.fail("用户名已存在");
        }

        System.out.println("用户注册");

        // 处理邀请码逻辑
        String inputInviteCode = user.getInvite_code();
        System.out.println("使用邀请码: [" + inputInviteCode + "]");

        if (inputInviteCode != null && !inputInviteCode.isEmpty()) {
            System.out.println("邀请码有效");

            User inviter = userRepository.findByInviteCode(inputInviteCode)
                    .orElseThrow(() -> new IllegalArgumentException("邀请码无效"));

            System.out.println("Inviter 查询结果: " + inviter);

            // 设置邀请关系
            user.setInviter(inviter);

            // 增加积分
            inviter.setScore((inviter.getScore() != null ? inviter.getScore() : 0f) + 20f);
            userRepository.save(inviter);

            System.out.println("准备根据ID更新邀请码为 NULL，用户ID = " + inviter.getUser_id());
            userRepository.clearInviteCode(inviter.getUser_id());
            System.out.println("更新邀请码为 NULL 的用户ID：" + inviter.getUser_id());

            // 发送通知
            Long user_id= inviter.getUser_id();
            String title="邀请码被使用奖励";
            String content="用户 [" + user.getUsername() + "] 使用了你的邀请码，积分增加 20";
            notificationRepository.insertNotification(
                    user_id,
                    title,
                    content,
                    LocalDateTime.now()
            );

        }

        // 设置新用户信息
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setLevel("Peasant");
        user.setUploadBytes(0L);
        user.setDownloadBytes(0L);
        user.setCreatedAt(LocalDateTime.now());
        user.setInvite_code(UUID.randomUUID().toString().substring(0, 8));


        // 生成passkey
        byte[] bytes = new byte[24];
        random.nextBytes(bytes);
        String passkey = Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);

        user.setPasskey(passkey);
        //userRepository.save(user);


        //user.setPasskey(UUID.randomUUID().toString().substring(0, 24));

        try {
            userRepository.save(user);
            // 🌟 给新用户发送“用户须知”通知
            Long newUserId = user.getUser_id(); // 注意：要保存后再获取ID
            String title = "🌟 用户须知 🌟";
            String content = """
                🌟 欢迎加入本站！
                
                🧭 请认真阅读以下社区规则：
                1.禁止发布非法资源，尊重版权。
                2.请保持良好的分享率，避免成为吸血用户。管理员会定期进行分享率考核，如果分享率过低就会被清退哦~
                3.每天签到、积极参与做种可获得更多积分与权限。长时间不登录也会被清退哦~
                4.账号仅限本人使用，严禁共享或出售账号。
                5.被举报或违规会导致警告、限权，严重者封号。
                
                🎉 感谢你的加入，祝你使用愉快！
                """;
            notificationRepository.insertNotification(newUserId, title, content, LocalDateTime.now());


            return ApiResponse.success("注册成功");
        } catch (Exception e) {
            return ApiResponse.fail("注册失败，系统错误: " + e.getMessage());
        }
    }

    @Override
    public User login(String username, String password) {
        try {
            // 1. 查找用户（不存在则抛出异常）
            User user = userRepository.findByUsername(username)
                    .orElseThrow(() -> new UsernameNotFoundException("用户不存在"));

            // 2. 验证密码
            if (!passwordEncoder.matches(password, user.getPassword())) {
                return null;
            }

            return user;
        } catch (UsernameNotFoundException e) {
            return null;
        }
    }

    @Override
    public User getUserProfile(Long userId){
        if (userId == null){
            return null;
        }
        return userRepository.findById(userId).get();
    }

    @Override
    @Transactional
    public void checkAndUpgradeUserLevel(User user) {
        float score = user.getScore() != null ? user.getScore() : 0f;

        String level;
        if (score >= 1000) {
            level = "Elite User";
        } else if (score >= 500) {
            level = "Power User";
        } else {
            level = "Peasant";
        }

        if (!level.equals(user.getLevel())) {
            user.setLevel(level);
            userRepository.save(user);
        }
    }

    @Override
    public void updateUser(User user) {
        userRepository.save(user); // JPA 会自动更新所有字段
    }


    @Override
    @Transactional
    public int deleteUsersWithLowRatio() {
        // 1. 查询所有用户
        List<User> allUsers = userRepository.findAll();

        // 2. 筛选低分享率用户ID
        List<Long> toDelete = allUsers.stream()
                .filter(user -> {
                    long upload = user.getUploadBytes() != null ? user.getUploadBytes() : 0L;
                    long download = user.getDownloadBytes() != null ? user.getDownloadBytes() : 0L;
                    return download != 0 && (float) upload / download < 0.5f;
                })
                .map(User::getUserId)
                .collect(Collectors.toList());

        // 3. 批量删除
        if (!toDelete.isEmpty()) {
            userRepository.deleteAllByIdInBatch(toDelete); // 使用批量删除
        }

        return toDelete.size();
    }

    @Override
    public User findById(Long id) {
        return userRepository.findById(id).orElse(null);
    }


}